import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import _extends from "@babel/runtime/helpers/esm/extends";
import _typeof from "@babel/runtime/helpers/esm/typeof";
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import { createVNode as _createVNode, resolveDirective as _resolveDirective } from "vue";
import _regeneratorRuntime from "@babel/runtime/regenerator";

var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) {
  function adopt(value) {
    return value instanceof P ? value : new P(function (resolve) {
      resolve(value);
    });
  }

  return new (P || (P = Promise))(function (resolve, reject) {
    function fulfilled(value) {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    }

    function rejected(value) {
      try {
        step(generator["throw"](value));
      } catch (e) {
        reject(e);
      }
    }

    function step(result) {
      result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
    }

    step((generator = generator.apply(thisArg, _arguments || [])).next());
  });
};

import VcUpload from '../vc-upload';
import UploadList from './UploadList';
import { uploadProps } from './interface';
import { file2Obj, getFileItem, removeFileItem, updateFileList } from './utils';
import { useLocaleReceiver } from '../locale-provider/LocaleReceiver';
import defaultLocale from '../locale/default';
import { computed, defineComponent, onMounted, ref, toRef } from 'vue';
import { flattenChildren, initDefaultProps } from '../_util/props-util';
import useMergedState from '../_util/hooks/useMergedState';
import devWarning from '../vc-util/devWarning';
import useConfigInject from '../_util/hooks/useConfigInject';
import classNames from '../_util/classNames';
import { useInjectFormItemContext } from '../form';
export var LIST_IGNORE = "__LIST_IGNORE_".concat(Date.now(), "__");
export default defineComponent({
  name: 'AUpload',
  inheritAttrs: false,
  props: initDefaultProps(uploadProps(), {
    type: 'select',
    multiple: false,
    action: '',
    data: {},
    accept: '',
    showUploadList: true,
    listType: 'text',
    disabled: false,
    supportServerRender: true
  }),
  setup: function setup(props, _ref) {
    var _this = this;

    var slots = _ref.slots,
        attrs = _ref.attrs,
        expose = _ref.expose;
    var formItemContext = useInjectFormItemContext();

    var _useMergedState = useMergedState(props.defaultFileList || [], {
      value: toRef(props, 'fileList'),
      postState: function postState(list) {
        var timestamp = Date.now();
        return (list !== null && list !== void 0 ? list : []).map(function (file, index) {
          if (!file.uid && !Object.isFrozen(file)) {
            file.uid = "__AUTO__".concat(timestamp, "_").concat(index, "__");
          }

          return file;
        });
      }
    }),
        _useMergedState2 = _slicedToArray(_useMergedState, 2),
        mergedFileList = _useMergedState2[0],
        setMergedFileList = _useMergedState2[1];

    var dragState = ref('drop');
    var upload = ref();
    onMounted(function () {
      devWarning(props.fileList !== undefined || attrs.value === undefined, 'Upload', '`value` is not a valid prop, do you mean `fileList`?');
      devWarning(props.transformFile === undefined, 'Upload', '`transformFile` is deprecated. Please use `beforeUpload` directly.');
      devWarning(props.remove === undefined, 'Upload', '`remove` props is deprecated. Please use `remove` event.');
    });

    var onInternalChange = function onInternalChange(file, changedFileList, event) {
      var _a, _b;

      var cloneList = _toConsumableArray(changedFileList); // Cut to match count


      if (props.maxCount === 1) {
        cloneList = cloneList.slice(-1);
      } else if (props.maxCount) {
        cloneList = cloneList.slice(0, props.maxCount);
      }

      setMergedFileList(cloneList);
      var changeInfo = {
        file: file,
        fileList: cloneList
      };

      if (event) {
        changeInfo.event = event;
      }

      (_a = props['onUpdate:fileList']) === null || _a === void 0 ? void 0 : _a.call(props, changeInfo.fileList);
      (_b = props.onChange) === null || _b === void 0 ? void 0 : _b.call(props, changeInfo);
      formItemContext.onFieldChange();
    };

    var mergedBeforeUpload = function mergedBeforeUpload(file, fileListArgs) {
      return __awaiter(_this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
        var beforeUpload, transformFile, parsedFile, result;
        return _regeneratorRuntime.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                beforeUpload = props.beforeUpload, transformFile = props.transformFile;
                parsedFile = file;

                if (!beforeUpload) {
                  _context.next = 13;
                  break;
                }

                _context.next = 5;
                return beforeUpload(file, fileListArgs);

              case 5:
                result = _context.sent;

                if (!(result === false)) {
                  _context.next = 8;
                  break;
                }

                return _context.abrupt("return", false);

              case 8:
                // Hack for LIST_IGNORE, we add additional info to remove from the list
                delete file[LIST_IGNORE];

                if (!(result === LIST_IGNORE)) {
                  _context.next = 12;
                  break;
                }

                Object.defineProperty(file, LIST_IGNORE, {
                  value: true,
                  configurable: true
                });
                return _context.abrupt("return", false);

              case 12:
                if (_typeof(result) === 'object' && result) {
                  parsedFile = result;
                }

              case 13:
                if (!transformFile) {
                  _context.next = 17;
                  break;
                }

                _context.next = 16;
                return transformFile(parsedFile);

              case 16:
                parsedFile = _context.sent;

              case 17:
                return _context.abrupt("return", parsedFile);

              case 18:
              case "end":
                return _context.stop();
            }
          }
        }, _callee);
      }));
    };

    var onBatchStart = function onBatchStart(batchFileInfoList) {
      // Skip file which marked as `LIST_IGNORE`, these file will not add to file list
      var filteredFileInfoList = batchFileInfoList.filter(function (info) {
        return !info.file[LIST_IGNORE];
      }); // Nothing to do since no file need upload

      if (!filteredFileInfoList.length) {
        return;
      }

      var objectFileList = filteredFileInfoList.map(function (info) {
        return file2Obj(info.file);
      }); // Concat new files with prev files

      var newFileList = _toConsumableArray(mergedFileList.value);

      objectFileList.forEach(function (fileObj) {
        // Replace file if exist
        newFileList = updateFileList(fileObj, newFileList);
      });
      objectFileList.forEach(function (fileObj, index) {
        // Repeat trigger `onChange` event for compatible
        var triggerFileObj = fileObj;

        if (!filteredFileInfoList[index].parsedFile) {
          // `beforeUpload` return false
          var originFileObj = fileObj.originFileObj;
          var clone;

          try {
            clone = new File([originFileObj], originFileObj.name, {
              type: originFileObj.type
            });
          } catch (e) {
            clone = new Blob([originFileObj], {
              type: originFileObj.type
            });
            clone.name = originFileObj.name;
            clone.lastModifiedDate = new Date();
            clone.lastModified = new Date().getTime();
          }

          clone.uid = fileObj.uid;
          triggerFileObj = clone;
        } else {
          // Inject `uploading` status
          fileObj.status = 'uploading';
        }

        onInternalChange(triggerFileObj, newFileList);
      });
    };

    var onSuccess = function onSuccess(response, file, xhr) {
      try {
        if (typeof response === 'string') {
          response = JSON.parse(response);
        }
      } catch (e) {
        /* do nothing */
      } // removed


      if (!getFileItem(file, mergedFileList.value)) {
        return;
      }

      var targetItem = file2Obj(file);
      targetItem.status = 'done';
      targetItem.percent = 100;
      targetItem.response = response;
      targetItem.xhr = xhr;
      var nextFileList = updateFileList(targetItem, mergedFileList.value);
      onInternalChange(targetItem, nextFileList);
    };

    var onProgress = function onProgress(e, file) {
      // removed
      if (!getFileItem(file, mergedFileList.value)) {
        return;
      }

      var targetItem = file2Obj(file);
      targetItem.status = 'uploading';
      targetItem.percent = e.percent;
      var nextFileList = updateFileList(targetItem, mergedFileList.value);
      onInternalChange(targetItem, nextFileList, e);
    };

    var onError = function onError(error, response, file) {
      // removed
      if (!getFileItem(file, mergedFileList.value)) {
        return;
      }

      var targetItem = file2Obj(file);
      targetItem.error = error;
      targetItem.response = response;
      targetItem.status = 'error';
      var nextFileList = updateFileList(targetItem, mergedFileList.value);
      onInternalChange(targetItem, nextFileList);
    };

    var handleRemove = function handleRemove(file) {
      var currentFile;
      var mergedRemove = props.onRemove || props.remove;
      Promise.resolve(typeof mergedRemove === 'function' ? mergedRemove(file) : mergedRemove).then(function (ret) {
        var _a, _b; // Prevent removing file


        if (ret === false) {
          return;
        }

        var removedFileList = removeFileItem(file, mergedFileList.value);

        if (removedFileList) {
          currentFile = _extends(_extends({}, file), {
            status: 'removed'
          });
          (_a = mergedFileList.value) === null || _a === void 0 ? void 0 : _a.forEach(function (item) {
            var matchKey = currentFile.uid !== undefined ? 'uid' : 'name';

            if (item[matchKey] === currentFile[matchKey] && !Object.isFrozen(item)) {
              item.status = 'removed';
            }
          });
          (_b = upload.value) === null || _b === void 0 ? void 0 : _b.abort(currentFile);
          onInternalChange(currentFile, removedFileList);
        }
      });
    };

    var onFileDrop = function onFileDrop(e) {
      var _a;

      dragState.value = e.type;

      if (e.type === 'drop') {
        (_a = props.onDrop) === null || _a === void 0 ? void 0 : _a.call(props, e);
      }
    };

    expose({
      onBatchStart: onBatchStart,
      onSuccess: onSuccess,
      onProgress: onProgress,
      onError: onError,
      fileList: mergedFileList,
      upload: upload
    });

    var _useConfigInject = useConfigInject('upload', props),
        prefixCls = _useConfigInject.prefixCls,
        direction = _useConfigInject.direction;

    var _useLocaleReceiver = useLocaleReceiver('Upload', defaultLocale.Upload, computed(function () {
      return props.locale;
    })),
        _useLocaleReceiver2 = _slicedToArray(_useLocaleReceiver, 1),
        locale = _useLocaleReceiver2[0];

    var renderUploadList = function renderUploadList(button, buttonVisible) {
      var removeIcon = props.removeIcon,
          previewIcon = props.previewIcon,
          downloadIcon = props.downloadIcon,
          previewFile = props.previewFile,
          onPreview = props.onPreview,
          onDownload = props.onDownload,
          disabled = props.disabled,
          isImageUrl = props.isImageUrl,
          progress = props.progress,
          itemRender = props.itemRender,
          iconRender = props.iconRender,
          showUploadList = props.showUploadList;

      var _ref2 = typeof showUploadList === 'boolean' ? {} : showUploadList,
          showDownloadIcon = _ref2.showDownloadIcon,
          showPreviewIcon = _ref2.showPreviewIcon,
          showRemoveIcon = _ref2.showRemoveIcon;

      return showUploadList ? _createVNode(UploadList, {
        "listType": props.listType,
        "items": mergedFileList.value,
        "previewFile": previewFile,
        "onPreview": onPreview,
        "onDownload": onDownload,
        "onRemove": handleRemove,
        "showRemoveIcon": !disabled && showRemoveIcon,
        "showPreviewIcon": showPreviewIcon,
        "showDownloadIcon": showDownloadIcon,
        "removeIcon": removeIcon,
        "previewIcon": previewIcon,
        "downloadIcon": downloadIcon,
        "iconRender": iconRender,
        "locale": locale.value,
        "isImageUrl": isImageUrl,
        "progress": progress,
        "itemRender": itemRender,
        "appendActionVisible": buttonVisible,
        "appendAction": button
      }, _extends({}, slots)) : button === null || button === void 0 ? void 0 : button();
    };

    return function () {
      var _classNames2;

      var _a, _b, _c;

      var listType = props.listType,
          disabled = props.disabled,
          type = props.type;

      var rcUploadProps = _extends(_extends({
        onBatchStart: onBatchStart,
        onError: onError,
        onProgress: onProgress,
        onSuccess: onSuccess
      }, props), {
        id: (_a = props.id) !== null && _a !== void 0 ? _a : formItemContext.id.value,
        prefixCls: prefixCls.value,
        beforeUpload: mergedBeforeUpload,
        onChange: undefined
      });

      delete rcUploadProps.remove; // Remove id to avoid open by label when trigger is hidden
      // !children: https://github.com/ant-design/ant-design/issues/14298
      // disabled: https://github.com/ant-design/ant-design/issues/16478
      //           https://github.com/ant-design/ant-design/issues/24197

      if (!slots.default || disabled) {
        delete rcUploadProps.id;
      }

      if (type === 'drag') {
        var _classNames;

        var dragCls = classNames(prefixCls.value, (_classNames = {}, _defineProperty(_classNames, "".concat(prefixCls.value, "-drag"), true), _defineProperty(_classNames, "".concat(prefixCls.value, "-drag-uploading"), mergedFileList.value.some(function (file) {
          return file.status === 'uploading';
        })), _defineProperty(_classNames, "".concat(prefixCls.value, "-drag-hover"), dragState.value === 'dragover'), _defineProperty(_classNames, "".concat(prefixCls.value, "-disabled"), disabled), _defineProperty(_classNames, "".concat(prefixCls.value, "-rtl"), direction.value === 'rtl'), _classNames), attrs.class);
        return _createVNode("span", null, [_createVNode("div", {
          "class": dragCls,
          "onDrop": onFileDrop,
          "onDragover": onFileDrop,
          "onDragleave": onFileDrop,
          "style": attrs.style
        }, [_createVNode(VcUpload, _objectSpread(_objectSpread({}, rcUploadProps), {}, {
          "ref": upload,
          "class": "".concat(prefixCls.value, "-btn")
        }), _objectSpread({
          default: function _default() {
            return [_createVNode("div", {
              "class": "".concat(prefixCls, "-drag-container")
            }, [(_b = slots.default) === null || _b === void 0 ? void 0 : _b.call(slots)])];
          }
        }, slots))]), renderUploadList()]);
      }

      var uploadButtonCls = classNames(prefixCls.value, (_classNames2 = {}, _defineProperty(_classNames2, "".concat(prefixCls.value, "-select"), true), _defineProperty(_classNames2, "".concat(prefixCls.value, "-select-").concat(listType), true), _defineProperty(_classNames2, "".concat(prefixCls.value, "-disabled"), disabled), _defineProperty(_classNames2, "".concat(prefixCls.value, "-rtl"), direction.value === 'rtl'), _classNames2));
      var children = flattenChildren((_c = slots.default) === null || _c === void 0 ? void 0 : _c.call(slots));

      var renderUploadButton = function renderUploadButton(uploadButtonStyle) {
        return _createVNode("div", {
          "class": uploadButtonCls,
          "style": uploadButtonStyle
        }, [_createVNode(VcUpload, _objectSpread(_objectSpread({}, rcUploadProps), {}, {
          "ref": upload
        }), slots)]);
      };

      if (listType === 'picture-card') {
        return _createVNode("span", {
          "class": classNames("".concat(prefixCls.value, "-picture-card-wrapper"), attrs.class)
        }, [renderUploadList(renderUploadButton, !!(children && children.length))]);
      }

      return _createVNode("span", {
        "class": attrs.class
      }, [renderUploadButton(children && children.length ? undefined : {
        display: 'none'
      }), renderUploadList()]);
    };
  }
});